# 函数可以作为一个对象,用变量名进行接收 然后进行传递
import functools
import json


def show():
    print("say hello!!!")


# 接收一个函数对象
def say_hello(xx):
    xx()


# say变量和show在内存中都指向同一个地址因此可以调用
say = show

say_hello(say)

#  lambd的原理就是换专业
# 判断是否是偶数
fun = lambda x: x % 2 == 0
# <function <lambda> at 0x000000000237DC10>
print(fun(10))
# 求两个数的乘积
print((lambda x, y: x * y)(2, 3))
# 把字符串的第一个字母大写
f2 = lambda x: x.replace(x[0], str(x[0]).upper(), 1)
print(f2("xuexue"))
# 定义三目输出最大值
print((lambda x, y: x if x > y else y)(123, 10))

# map 根据提供函数指定序列做映射
# 集合里面给个字符大写
lang_list = ["java", "python", "go", "c++"]
new_lang_list = map(lambda x: x.replace(x[0], str(x[0]).upper(), 1), lang_list)
print(list(new_lang_list))


# 自己实现
def my_map(f, target_list):
    ret_list = []
    for val in target_list:
        ret_list.append(f(val))
    return ret_list


# map辉哥集合里面数据当做参数去方法里面执行形成新的集合并且返回

ret = my_map(lambda x: x.replace(x[0], str(x[0]).upper(), 1), lang_list)
print("my_map:", ret)

# reduce 函数会将参数序列中的元素进行累加

result_1 = functools.reduce((lambda x, y: x * y), [x for x in range(1, 7)])
print((lambda x, y: x ** y)(3, 2))


def f(x, y):
    # print(x ** y)
    return x ** y


# 第一次 2**3=8
# 第一次 8**4=4096
result_2 = functools.reduce(f, [2, 3, 4])
print(result_2)
# print(f(8, 4))

result_3 = functools.reduce(lambda x, y: x + y, [2, 3, 4])
print(result_3)


class Person:

    def __init__(self, *kwargs, name=None, user_id=None, age=0):
        self.id = user_id
        self.name = name
        self.age = age

    def __str__(self):
        return f"[id={self.id},name={self.name},age={self.age}]"


p_list = [Person(user_id=1, name="学学", age=14), Person(user_id=3, name="瑶瑶", age=16),
          Person(user_id=2, name="莉莉", age=17)]
# filter 对元素进行过滤
# 找到最长的公共串
str_list = ['asd', '1321', "asd123", "12345", "12345aa"]
# 过滤是字符串的
filter1 = filter(lambda x: str(x).isdigit(), str_list)
# 按照年龄排序
result_4 = sorted(p_list, key=lambda x: x.age, reverse=True)
result_5 = sorted(p_list, key=lambda x: x.id, reverse=True)
# print(list(filter1))
# for p in result_4:
#     print(p)
# 根据年龄进行过滤
result_6 = filter(lambda x: x.age > 14, p_list)
# ensure_ascii 默认为True 会把中文转为ascii码
# sort_keys 按照字符排序 True是升序
# skipkeys dict的对象只能是基本数据类似（int，float,bool,None,str）
# ,如果是其它类型，那么在编码的过程中就会抛出ValueError异常。shipkeys可以跳过那些非string对象的key的处理，就是不处理。
# default=lambda obj: obj.__dict__ json序列化规则 可以自定义 在对象里面实现__dict__函数
# indent=0 空格长度
person_json_str = json.dumps(list(result_6), default=lambda obj: obj.__dict__, ensure_ascii=False)
print("person_json_str:", person_json_str)

# for p in result_5:
#     print(p)
